home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / nslookup / RCS / getinfo.c,v < prev    next >
Encoding:
Text File  |  1988-11-27  |  18.7 KB  |  789 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.1
  10. date     88.11.23.13.39.00;  author douglis;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @original src from monet.
  17. @
  18.  
  19.  
  20.  
  21. 1.1
  22. log
  23. @Initial revision
  24. @
  25. text
  26. @/*
  27.  * Copyright (c) 1985 Regents of the University of California.
  28.  * All rights reserved.
  29.  *
  30.  * Redistribution and use in source and binary forms are permitted
  31.  * provided that the above copyright notice and this paragraph are
  32.  * duplicated in all such forms and that any documentation,
  33.  * advertising materials, and other materials related to such
  34.  * distribution and use acknowledge that the software was developed
  35.  * by the University of California, Berkeley.  The name of the
  36.  * University may not be used to endorse or promote products derived
  37.  * from this software without specific prior written permission.
  38.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  39.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  40.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  41.  */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@@(#)getinfo.c    5.18 (Berkeley) 6/18/88";
  45. #endif /* not lint */
  46.  
  47. /*
  48.  *******************************************************************************
  49.  *
  50.  *  getinfo.c --
  51.  *
  52.  *    Routines to create requests to name servers 
  53.  *    and interpret the answers.
  54.  *
  55.  *    Adapted from 4.3BSD BIND gethostnamadr.c
  56.  *
  57.  *******************************************************************************
  58.  */
  59.  
  60. #include <sys/types.h>
  61. #include <sys/socket.h>
  62. #include <netinet/in.h>
  63. #include <stdio.h>
  64. #include <ctype.h>
  65. #include <arpa/nameser.h>
  66. #include <resolv.h>
  67. #include "res.h"
  68.  
  69. extern char *_res_resultcodes[];
  70. extern char *res_skip();
  71.  
  72. #define    MAXALIASES    35
  73. #define MAXADDRS    35
  74. #define MAXDOMAINS    35
  75. #define MAXSERVERS    10
  76.  
  77. static char *addr_list[MAXADDRS + 1];
  78.  
  79. static char *host_aliases[MAXALIASES];
  80. static int   host_aliases_len[MAXALIASES];
  81. static char  hostbuf[BUFSIZ+1];
  82.  
  83. typedef struct {
  84.     char *name;
  85.     char *domain[MAXDOMAINS];
  86.     int   numDomains;
  87.     char *address[MAXADDRS];
  88.     int   numAddresses;
  89. } ServerTable;
  90.  
  91. ServerTable server[MAXSERVERS];
  92.  
  93. typedef union {
  94.     HEADER qb1;
  95.     char qb2[PACKETSZ];
  96. } querybuf;
  97.  
  98. typedef union {
  99.     long al;
  100.     char ac;
  101. } align;
  102.  
  103. #define GetShort(cp)    _getshort(cp); cp += sizeof(unsigned short);
  104.  
  105.  
  106. /*
  107.  *******************************************************************************
  108.  *
  109.  *  GetAnswer --
  110.  *
  111.  *    Interprets an answer packet and retrieves the following
  112.  *    information:
  113.  *
  114.  *  Results:
  115.  *      SUCCESS         the info was retrieved.
  116.  *      NO_INFO         the packet did not contain an answer.
  117.  *    NONAUTH        non-authoritative information was found.
  118.  *      ERROR           the answer was malformed.
  119.  *      Other errors    returned in the packet header.
  120.  *
  121.  *******************************************************************************
  122.  */
  123.  
  124. static int
  125. GetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isserver)
  126.     struct in_addr     *nsAddrPtr;
  127.     char         *msg;
  128.     int         queryType;
  129.     int         msglen;
  130.     Boolean         iquery;
  131.     register HostInfo    *hostPtr;
  132.     Boolean        isserver;
  133. {
  134.     register HEADER     *headerPtr;
  135.     register char     *cp;
  136.     querybuf         answer;
  137.     char         *eom, *bp, **aliasPtr;
  138.     char         **addrPtr;
  139.     char        *namePtr;
  140.     char        *dnamePtr;
  141.     int         type, class;
  142.     int         qdcount, ancount, arcount, nscount, buflen;
  143.     int         origClass;
  144.     int         numAliases = 0;
  145.     int         numAddresses = 0;
  146.     int         n, i, j;
  147.     int         len;
  148.     int         dlen;
  149.     int         status;
  150.     int            numServers;
  151.     Boolean         haveanswer;
  152.  
  153.  
  154.     /*
  155.      *  If the hostPtr was used before, free up the calloc'd areas.
  156.      */
  157.     FreeHostInfoPtr(hostPtr);
  158.     
  159.     status = SendRequest(nsAddrPtr, msg, msglen, (char *) &answer, 
  160.                 sizeof(answer), &n);
  161.  
  162.     if (status != SUCCESS) {
  163.         if (_res.options & RES_DEBUG2)
  164.             printf("SendRequest failed\n");
  165.         return (status);
  166.     }
  167.     eom = (char *) &answer + n;
  168.  
  169.     headerPtr = (HEADER *) &answer;
  170.     qdcount = ntohs(headerPtr->qdcount);
  171.     ancount = ntohs(headerPtr->ancount);
  172.     arcount = ntohs(headerPtr->arcount);
  173.     nscount = ntohs(headerPtr->nscount);
  174.  
  175.     if (headerPtr->rcode != NOERROR) {
  176.     if (_res.options & RES_DEBUG && !isserver) {
  177.         printf("Failed: %s, num. answers = %d, ns = %d, additional = %d\n", 
  178.             _res_resultcodes[headerPtr->rcode], ancount, nscount,
  179.             arcount);
  180.     }
  181.     return (headerPtr->rcode);
  182.     }
  183.  
  184.     /*
  185.      * If there are no answer, n.s. or additional records 
  186.      * then return with an error.
  187.      */
  188.     if (ancount == 0 && nscount == 0 && arcount == 0) {
  189.     return (NO_INFO);
  190.     }
  191.  
  192.  
  193.     bp        = hostbuf;
  194.     buflen = sizeof(hostbuf);
  195.     cp        = (char *) &answer + sizeof(HEADER);
  196.  
  197.     /*
  198.      * For inverse queries, the desired information is returned
  199.      * in the question section. If there are no question records,
  200.      * return with an error.
  201.      *
  202.      */
  203.     if (qdcount != 0) {
  204.     if (iquery) {
  205.         if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) {
  206.         return (ERROR);
  207.         }
  208.         cp += n + QFIXEDSZ;
  209.         len = strlen(bp) + 1;
  210.         hostPtr->name = Calloc(1, len);
  211.         bcopy(bp, hostPtr->name, len);
  212.     } else {
  213.         cp += dn_skipname(cp, eom) + QFIXEDSZ;
  214.     }
  215.     while (--qdcount > 0) {
  216.         cp += dn_skipname(cp, eom) + QFIXEDSZ;
  217.     }
  218.     } else if (iquery) {
  219.     return (NO_INFO);
  220.     }
  221.  
  222.     aliasPtr     = host_aliases;
  223.     addrPtr    = addr_list;
  224.     haveanswer     = FALSE;
  225.  
  226.     /*
  227.      * Scan through the answer resource records.
  228.      * Answers for address query types are saved.
  229.      * Other query type answers are just printed.
  230.      */
  231.     if (!isserver && !headerPtr->aa && headerPtr->ancount != 0) {
  232.     printf("Non-authoritative answer:\n");
  233.     }
  234.     while (--ancount >= 0 && cp < eom) {
  235.     if (queryType != T_A) {
  236.         if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) {
  237.         return(ERROR);
  238.         }
  239.         continue;
  240.     } else {
  241.         if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
  242.         return(ERROR);
  243.         }
  244.         cp   += n;
  245.         type  = GetShort(cp);
  246.         class = GetShort(cp);
  247.         cp   += sizeof(u_long);     /* skip TTL */
  248.         dlen  = GetShort(cp);
  249.         if (type == T_CNAME) {
  250.         /*
  251.          * Found an alias.
  252.          */
  253.         cp += dlen;
  254.         if (aliasPtr >= &host_aliases[MAXALIASES-1]) {
  255.             continue;
  256.         }
  257.         *aliasPtr++ = bp;
  258.         n = strlen(bp) + 1;
  259.         host_aliases_len[numAliases] = n;
  260.         numAliases++;
  261.         bp += n;
  262.         buflen -= n;
  263.         continue;
  264.         } else if (type == T_PTR) {
  265.         /*
  266.          *  Found a "pointer" to the real name.
  267.          */
  268.         if((n= dn_expand((char *)&answer, eom, cp, bp,buflen)) < 0) {
  269.             cp += n;
  270.             continue;
  271.         }
  272.         cp += n;
  273.         len = strlen(bp) + 1;
  274.         hostPtr->name = Calloc(1, len);
  275.         bcopy(bp, hostPtr->name, len);
  276.         haveanswer = TRUE;
  277.         break;
  278.         } else if (type != T_A) {
  279.         cp += dlen;
  280.         continue;
  281.         }
  282.         if (haveanswer) {
  283.         /*
  284.          * If we've already got 1 address, we aren't interested
  285.          * in addresses with a different length or class.
  286.          */
  287.         if (dlen != hostPtr->addrLen) {
  288.             cp += dlen;
  289.             continue;
  290.         }
  291.         if (class != origClass) {
  292.             cp += dlen;
  293.             continue;
  294.         }
  295.         } else {
  296.         /*
  297.          * First address: record its length and class so we
  298.          * only save additonal ones with the same attributes.
  299.          */
  300.         hostPtr->addrLen = dlen;
  301.         origClass = class;
  302.         hostPtr->addrType = (class == C_IN) ? AF_INET : AF_UNSPEC;
  303.         if (!iquery) {
  304.             len = strlen(bp) + 1;
  305.             hostPtr->name = Calloc(1, len);
  306.             bcopy(bp, hostPtr->name, len);
  307.         }
  308.         }
  309.         bp += (((u_long)bp) % sizeof(align));
  310.  
  311.         if (bp + dlen >= &hostbuf[sizeof(hostbuf)]) {
  312.         if (_res.options & RES_DEBUG) {
  313.             printf("Size (%d) too big\n", dlen);
  314.         }
  315.         break;
  316.         }
  317.         bcopy(cp, *addrPtr++ = bp, dlen);
  318.         bp +=dlen;
  319.         cp += dlen;
  320.         numAddresses++;
  321.         haveanswer = TRUE; 
  322.     }
  323.     }
  324.  
  325.     if (queryType == T_A && haveanswer) {
  326.  
  327.     /*
  328.      *  Go through the alias and address lists and return them
  329.      *  in the hostPtr variable.
  330.      */
  331.  
  332.     if (numAliases > 0) {
  333.         hostPtr->aliases = (char **) Calloc(1 + numAliases, sizeof(char *));
  334.         for (i = 0; i < numAliases; i++) {
  335.         hostPtr->aliases[i] = Calloc(1, host_aliases_len[i]);
  336.         bcopy(host_aliases[i], hostPtr->aliases[i],host_aliases_len[i]);
  337.         }
  338.         hostPtr->aliases[i] = NULL;
  339.     }
  340.     if (numAddresses > 0) {
  341.         hostPtr->addrList = (char **)Calloc(1+numAddresses, sizeof(char *));
  342.         for (i = 0; i < numAddresses; i++) {
  343.         hostPtr->addrList[i] = Calloc(1, hostPtr->addrLen);
  344.         bcopy(addr_list[i], hostPtr->addrList[i], hostPtr->addrLen);
  345.         }
  346.         hostPtr->addrList[i] = NULL;
  347.     }
  348. #ifdef verbose
  349.     if (headerPtr->aa || nscount == 0) {
  350.         hostPtr->servers = NULL;
  351.         return (SUCCESS);
  352.     }
  353. #else
  354.     hostPtr->servers = NULL;
  355.     return (SUCCESS);
  356. #endif
  357.     }
  358.  
  359.     /*
  360.      * At this point, for the T_A query type, only empty answers remain.
  361.      * For other query types, additional information might be found
  362.      * in the additional resource records part.
  363.      */
  364.  
  365.     cp = res_skip((char *) &answer, 2, eom);
  366.  
  367.     numServers = 0;
  368.     while (--nscount >= 0 && cp < eom) {
  369.     /*
  370.      *  Go through the NS records and retrieve the names of hosts 
  371.      *  that serve the requested domain.
  372.      */
  373.  
  374.     if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
  375.         return(ERROR);
  376.     }
  377.     cp += n;
  378.     len = strlen(bp) + 1;
  379.     dnamePtr = Calloc(1, len);   /* domain name */
  380.     bcopy(bp, dnamePtr, len);
  381.  
  382.     type  = GetShort(cp);
  383.     class = GetShort(cp);
  384.     cp   += sizeof(u_long);     /* skip TTL */
  385.     dlen  = GetShort(cp);
  386.  
  387.     if (type != T_NS) {
  388.         cp += dlen;
  389.     } else {
  390.         Boolean    found;
  391.  
  392.         if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
  393.         return(ERROR);
  394.         }
  395.         cp += n;
  396.         len = strlen(bp) + 1;
  397.         namePtr = Calloc(1, len); /* server host name */
  398.         bcopy(bp, namePtr, len);
  399.  
  400.         /*
  401.         * Store the information keyed by the server host name.
  402.         */
  403.         found = FALSE;
  404.         for (j = 0; j < numServers; j++) {
  405.         if (strcmp(namePtr, server[j].name) == 0) {
  406.             found = TRUE;
  407.             free(namePtr);
  408.             break;
  409.         }
  410.         }
  411.         if (found) {
  412.         server[j].numDomains++;
  413.         if (server[j].numDomains <= MAXDOMAINS) {
  414.             server[j].domain[server[j].numDomains-1] = dnamePtr;
  415.         }
  416.         } else {
  417.         if (numServers >= MAXSERVERS) {
  418.             break;
  419.         }
  420.         server[numServers].name = namePtr;
  421.         server[numServers].domain[0] = dnamePtr;
  422.         server[numServers].numDomains = 1;
  423.         server[numServers].numAddresses = 0;
  424.         numServers++;
  425.         }
  426.     }
  427.     }
  428.  
  429.     if (!headerPtr->aa && (queryType != T_A) && arcount > 0) {
  430.     printf("Authoritative answers can be found from:\n");
  431.     }
  432.  
  433.     /*
  434.      * Additional resource records contain addresses of servers.
  435.      */
  436.     cp = res_skip((char *) &answer, 3, eom);
  437.     while (--arcount >= 0 && cp < eom) {
  438.     /*
  439.      * If we don't need to save the record, just print it.
  440.      */
  441.     if (queryType != T_A) {
  442.         if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) {
  443.         return(ERROR);
  444.         }
  445.         continue;
  446.  
  447.     } else {
  448.       if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
  449.           break;
  450.       }
  451.       cp   += n;
  452.       type  = GetShort(cp);
  453.       class = GetShort(cp);
  454.       cp   += sizeof(u_long);     /* skip TTL */
  455.       dlen  = GetShort(cp);
  456.  
  457.       if (type != T_A)  {
  458.           cp += dlen;
  459.           continue;
  460.       } else {
  461.           for (j = 0; j < numServers; j++) {
  462.             if (strcmp(bp, server[j].name) == 0) {
  463.           server[j].numAddresses++;
  464.           if (server[j].numAddresses <= MAXADDRS) {
  465.            server[j].address[server[j].numAddresses-1] = Calloc(1,dlen);
  466.            bcopy(cp,server[j].address[server[j].numAddresses-1],dlen);
  467.            break;
  468.           }
  469.             }
  470.           }
  471.           cp += dlen;
  472.       }
  473.       }
  474.     }
  475.  
  476.     /*
  477.      * If we are returning name server info, transfer it to the hostPtr.
  478.      */
  479.     if (numServers > 0) {
  480.     hostPtr->servers = (ServerInfo **) 
  481.                     Calloc(numServers+1, sizeof(ServerInfo *));
  482.  
  483.     for (i = 0; i < numServers; i++) {
  484.         hostPtr->servers[i] = (ServerInfo *) Calloc(1, sizeof(ServerInfo));
  485.         hostPtr->servers[i]->name = server[i].name;
  486.  
  487.  
  488.         hostPtr->servers[i]->domains = (char **)
  489.                     Calloc(server[i].numDomains+1,sizeof(char *));
  490.         for (j = 0; j < server[i].numDomains; j++) {
  491.         hostPtr->servers[i]->domains[j] = server[i].domain[j];
  492.         }
  493.         hostPtr->servers[i]->domains[j] = NULL;
  494.  
  495.  
  496.         hostPtr->servers[i]->addrList = (char **)
  497.                   Calloc(server[i].numAddresses+1,sizeof(char *));
  498.         for (j = 0; j < server[i].numAddresses; j++) {
  499.         hostPtr->servers[i]->addrList[j] = server[i].address[j];
  500.         }
  501.         hostPtr->servers[i]->addrList[j] = NULL;
  502.  
  503.     }
  504.     hostPtr->servers[i] = NULL;
  505.     }
  506.  
  507.  
  508.     if (queryType != T_A) {
  509.     return(SUCCESS);
  510.     } else {
  511.     return(NONAUTH);
  512.     }
  513. }
  514.  
  515. /*
  516. *******************************************************************************
  517. *
  518. *  GetHostInfo --
  519. *
  520. *    Retrieves host name, address and alias information
  521. *    for a domain.
  522. *
  523. *  Results:
  524. *    ERROR        - res_mkquery failed.
  525. *    + return values from GetAnswer()
  526. *
  527. *******************************************************************************
  528. */
  529.  
  530. int
  531. GetHostInfo(nsAddrPtr, queryClass, queryType, name, hostPtr, isserver)
  532.     struct in_addr    *nsAddrPtr;
  533.     int         queryClass;
  534.     int         queryType;
  535.     char         *name;
  536.     HostInfo         *hostPtr;
  537.     Boolean        isserver;
  538. {
  539.     int          n;
  540.     int          result;
  541.     register char    *cp, **domain;
  542.     extern char        *hostalias();
  543.  
  544.     /* catch explicit addresses */
  545.     if (isdigit(*name) && (queryType == T_A)) {
  546.     long ina;
  547.  
  548.     ina = inet_addr(name);
  549.  
  550.     if (ina == -1)
  551.         return(ERROR);
  552.  
  553.     hostPtr->name = Calloc(strlen(name)+3, 1);
  554.     (void)sprintf(hostPtr->name,"[%s]",name);
  555.     hostPtr->aliases = NULL;
  556.     hostPtr->servers = NULL;
  557.     hostPtr->addrType = AF_INET;
  558.     hostPtr->addrLen = 4;
  559.     hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
  560.     hostPtr->addrList[0] = Calloc(sizeof(long), sizeof(char));
  561.     bcopy((char *)&ina,hostPtr->addrList[0],sizeof(ina));
  562.     hostPtr->addrList[1] = 0;
  563.  
  564.     return(SUCCESS);
  565.     }
  566.  
  567.     for (cp = name, n = 0; *cp; cp++)
  568.         if (*cp == '.')
  569.             n++;
  570.     if ((n && *--cp == '.') ||
  571.     (isserver == 0 && (_res.options & RES_DEFNAMES) == 0)) {
  572.         int defflag = _res.options & RES_DEFNAMES;
  573.  
  574.         _res.options &= ~RES_DEFNAMES;
  575.         if (n && *cp == '.')
  576.             *cp = 0;
  577.         result = GetHostDomain(nsAddrPtr, queryClass, queryType,
  578.             name, (char *)NULL, hostPtr, isserver);
  579.         if (n && *cp == 0)
  580.             *cp = '.';
  581.         if (defflag)
  582.             _res.options |= RES_DEFNAMES;
  583.         return (result);
  584.     }
  585.     if (n == 0 && (cp = hostalias(name)))
  586.         return (GetHostDomain(nsAddrPtr, queryClass, queryType,
  587.             cp, (char *)NULL, hostPtr, isserver));
  588.     for (domain = _res.dnsrch; *domain; domain++) {
  589.         result = GetHostDomain(nsAddrPtr, queryClass, queryType,
  590.             name, *domain, hostPtr, isserver);
  591.         if ((result != NXDOMAIN && result != NO_INFO) ||
  592.         (_res.options & RES_DNSRCH) == 0)
  593.             return (result);
  594.     }
  595.     if (n)
  596.         return (GetHostDomain(nsAddrPtr, queryClass, queryType,
  597.             name, (char *)NULL, hostPtr, isserver));
  598.     return (result);
  599. }
  600.  
  601. GetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isserver)
  602.     struct in_addr    *nsAddrPtr;
  603.     int         queryClass;
  604.     int         queryType;
  605.     char         *name, *domain;
  606.     HostInfo        *hostPtr;
  607.     Boolean        isserver;
  608. {
  609.     querybuf buf;
  610.     char nbuf[2*MAXDNAME+2];
  611.     int n;
  612.  
  613.     if (domain) {
  614.         (void)sprintf(nbuf, "%.*s.%.*s",
  615.             MAXDNAME, name, MAXDNAME, domain);
  616.         name = nbuf;
  617.     }
  618.     n = res_mkquery(QUERY, name, queryClass, queryType,
  619.             (char *)0, 0, (char *)0, (char *) &buf, sizeof(buf));
  620.     if (n < 0) {
  621.     if (_res.options & RES_DEBUG) {
  622.         printf("Res_mkquery failed\n");
  623.     }
  624.     return (ERROR);
  625.     }
  626.  
  627.     n = GetAnswer(nsAddrPtr, queryType, (char *) &buf, n, 0, hostPtr,
  628.     isserver);
  629.  
  630.     /*
  631.      * GetAnswer didn't find a name, so set it to the specified one.
  632.      */
  633.     if (n == NONAUTH) {
  634.     if (hostPtr->name == NULL) {
  635.         int len = strlen(name) + 1;
  636.         hostPtr->name = Calloc(len, sizeof(char));
  637.         bcopy(name, hostPtr->name, len);
  638.     }
  639.     }
  640.     return(n);
  641. }
  642.  
  643.  
  644. /*
  645. *******************************************************************************
  646. *
  647. *  FindHostInfo --
  648. *
  649. *    Performs an inverse query to find the host name
  650. *    that corresponds to the given address.
  651. *
  652. *  Results:
  653. *    ERROR        - res_mkquery failed.
  654. *    + return values from GetAnswer()
  655. *
  656. *******************************************************************************
  657. */
  658.  
  659. int
  660. FindHostInfo(nsAddrPtr, address, len, hostPtr)
  661.     struct in_addr     *nsAddrPtr;
  662.     struct in_addr    *address;
  663.     int         len;
  664.     HostInfo         *hostPtr;
  665. {
  666.     int      n;
  667.     querybuf buf;
  668.  
  669.     n = res_mkquery(IQUERY, (char *)0, C_IN, T_A,
  670.         (char *)address, len, (char *)0, (char *) &buf, sizeof(buf));
  671.     if (n < 0) {
  672.     if (_res.options & RES_DEBUG) {
  673.         printf("Res_mkquery failed\n");
  674.     }
  675.     return (ERROR);
  676.     }
  677.     return(GetAnswer(nsAddrPtr, T_A, (char *) &buf, n, 1, hostPtr, 1));
  678. }
  679.  
  680. /*
  681. *******************************************************************************
  682. *
  683. *  FreeHostInfoPtr --
  684. *
  685. *    Deallocates all the calloc'd areas for a HostInfo variable.
  686. *
  687. *******************************************************************************
  688. */
  689.  
  690. void
  691. FreeHostInfoPtr(hostPtr)
  692.     register HostInfo *hostPtr;
  693. {
  694.     int i, j;
  695.  
  696.     if (hostPtr->name != NULL) {
  697.     free(hostPtr->name);
  698.     hostPtr->name = NULL;
  699.     }
  700.  
  701.     if (hostPtr->aliases != NULL) {
  702.     i = 0;
  703.     while (hostPtr->aliases[i] != NULL) {
  704.         free(hostPtr->aliases[i]);
  705.         i++;
  706.     }
  707.     free((char *)hostPtr->aliases);
  708.     hostPtr->aliases = NULL;
  709.     }
  710.  
  711.     if (hostPtr->addrList != NULL) {
  712.     i = 0;
  713.     while (hostPtr->addrList[i] != NULL) {
  714.         free(hostPtr->addrList[i]);
  715.         i++;
  716.     }
  717.     free((char *)hostPtr->addrList);
  718.     hostPtr->addrList = NULL;
  719.     }
  720.  
  721.     if (hostPtr->servers != NULL) {
  722.     i = 0;
  723.     while (hostPtr->servers[i] != NULL) {
  724.  
  725.         if (hostPtr->servers[i]->name != NULL) {
  726.         free(hostPtr->servers[i]->name);
  727.         }
  728.  
  729.         if (hostPtr->servers[i]->domains != NULL) {
  730.         j = 0;
  731.         while (hostPtr->servers[i]->domains[j] != NULL) {
  732.             free(hostPtr->servers[i]->domains[j]);
  733.             j++;
  734.         }
  735.         free((char *)hostPtr->servers[i]->domains);
  736.         }
  737.  
  738.         if (hostPtr->servers[i]->addrList != NULL) {
  739.         j = 0;
  740.         while (hostPtr->servers[i]->addrList[j] != NULL) {
  741.             free(hostPtr->servers[i]->addrList[j]);
  742.             j++;
  743.         }
  744.         free((char *)hostPtr->servers[i]->addrList);
  745.         }
  746.         free((char *)hostPtr->servers[i]);
  747.         i++;
  748.     }
  749.     free((char *)hostPtr->servers);
  750.     hostPtr->servers = NULL;
  751.     }
  752. }
  753.  
  754. /*
  755. *******************************************************************************
  756. *
  757. *  GetHostList --
  758. *
  759. *    Performs a completion query when given an incomplete name.
  760. *
  761. *    Still under development.
  762. *
  763. *******************************************************************************
  764. */
  765.  
  766. #if  notdef
  767.  
  768. int
  769. GetHostList(nsAddrPtr, queryType, name, defaultName, hostPtr)
  770.     struct in_addr     *nsAddrPtr;
  771.     int         queryType;
  772.     char         *name, *defaultName;
  773.     HostInfo         *hostPtr;
  774. {
  775.     int     n;
  776.     querybuf    buf;
  777.  
  778.     n = res_mkquery(CQUERYM, name, C_IN, T_A, defaultName, 0, (char *)0,
  779.         (char *) &buf, sizeof(buf));
  780.     if (n < 0) {
  781.         if (_res.options & RES_DEBUG)
  782.             printf("Res_mkquery failed\n");
  783.         return (ERROR);
  784.     }
  785.     return(GetAnswer(nsAddrPtr, queryType, (char *)&buf, n, 0, hostPtr, 1));
  786. }
  787. #endif  notdef
  788. @
  789.